package com.mbc.hr.manager;

import java.util.ArrayList;
import java.util.List;

import com.mbc.common.CommonConstants.RecordStatus;
import com.mbc.common.exception.DataCannotBeUpdated;
import com.mbc.common.manager.AbstractMgr;
import com.mbc.common.param.CriteriaParams;
import com.mbc.common.utils.KeyGenerator;
import com.mbc.hr.data.EmployeeGroupData;
import com.mbc.hr.data.EmployeeGroupDataList;
import com.mbc.hr.entities.EmployeeGroup;

public class EmployeeGroupMgr extends AbstractMgr {
	public EmployeeGroupMgr(){}
	
	public EmployeeGroupMgr(String sessionId){
		this.sessionId = sessionId;
	}
	
	public void createEmployeeGroup(EmployeeGroup employeeGroup)throws Exception{
		openConnection();
		try {
			beginTransaction();
			employeeGroup.setEmployeeGroupID(KeyGenerator.generateKey(entityManager));
			entityManager.persist(employeeGroup);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public void updateEmployeeGroup(EmployeeGroup employeeGroup)throws Exception{
		openConnection();
		try {
			beginTransaction();
			String l_jqQuery = "SELECT count(e.employeeID) FROM Employee e WHERE e.employeeGroupID = :employeeGroupID AND e.status <> :status";
			Long l_count = entityManager.createQuery(l_jqQuery, Long.class)
					.setParameter("employeeGroupID", employeeGroup.getEmployeeGroupID())
					.setParameter("status", RecordStatus.delete)
					.getSingleResult();
			if(l_count > 0)
				throw new DataCannotBeUpdated("Employee Group cannot be updated because it is stored in the employee table.");
			entityManager.merge(employeeGroup);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public void deleteEmployeeGroup(long employeeGroupId)throws Exception{
		openConnection();
		try {
			beginTransaction();
			EmployeeGroup l_empGroup = entityManager.find(EmployeeGroup.class, employeeGroupId);
			entityManager.remove(l_empGroup);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public EmployeeGroup findEmployeeGroup(long employeeGroupId)throws Exception{
		openConnection();
		try {
			return entityManager.find(EmployeeGroup.class, employeeGroupId);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public List<EmployeeGroup> getAllEmployeeGroup()throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("EmployeeGroup.findAll",EmployeeGroup.class).getResultList();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	@SuppressWarnings("unchecked")
	public EmployeeGroupDataList getEmployeeGroupList(CriteriaParams cri)throws Exception{
		openConnection();
		try {
            String l_cri = " and ( eg.name like '%" + cri.getKeyword() + "%' or ap.description like '%" + cri.getKeyword() + "%' or ls.description like '%" + cri.getKeyword() + "%')";
            
            String l_searchJPQL = "select eg.employeeGroupID, eg.name, ap.description, ls.description from EmployeeGroup eg, LeaveScheme ls, AttendancePolicy ap where eg.leaveSchemeID = ls.leaveSchemeID and eg.attendancePolicyID = ap.attendancePolicyID " + l_cri;
            

            List<EmployeeGroupData> l_entityList = new ArrayList<EmployeeGroupData>();
            
            List<Object[]> l_results = entityManager.createQuery(l_searchJPQL)
                    .setFirstResult(cri.getIndex())
                    .setMaxResults(cri.getSize())
                    .getResultList();
            
            for (Object[] l_result : l_results) {
            	EmployeeGroupData l_data = new EmployeeGroupData();
            	l_data.setEmployeeGroupId(Long.parseLong(l_result[0].toString()));
            	l_data.setName(l_result[1].toString());
            	l_data.setAttendancePolicyDescription(l_result[2].toString());
            	l_data.setLeaveSchemeDescription(l_result[3].toString());
            	l_entityList.add(l_data);
			}
            
            EmployeeGroupDataList l_dataList = new EmployeeGroupDataList();
            l_dataList.setEntityList(l_entityList);
            
            if(cri.getIndex() == 0){
            	String l_countQuery = "select count(eg.employeeGroupID) from EmployeeGroup eg, LeaveScheme ls, AttendancePolicy ap where eg.leaveSchemeID = ls.leaveSchemeID and eg.attendancePolicyID = ap.attendancePolicyID " + l_cri;
            	l_dataList.setTotalRecord(entityManager.createQuery(l_countQuery, Long.class).getSingleResult());
            }
			return l_dataList;
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
}